package ca.concordia.soen6011.tests;

/**
 * Test data item
 * 
 * A representation class for a single row in the test
 * data CSV file
 * 
 * @author Mirza, Musab Masood
 * @since July-August 2014
 * @copyright TRANSIENT FUNCTION CALCULATOR is a team project for the SOEN 6011
 *            course delivered by Dr. Kamthan, Pankaj at Concordia University,
 *            Montreal for the summer 2014 session.
 */
class TestDataItem{

	private char functionCode = 'a';
	private double x = 0;
	private double precision = 0.01;
	private double expectedOutput = 0;
	private boolean undefinedOutput = false;
	private boolean infiniteOutput = false;
	private String line = "";
	
	/**
	 * The constructor to parse a line from the test data
	 * file into the specific properties
	 * @param str
	 * @throws Exception 
	 */
	public TestDataItem(String line) throws Exception{
		
		String[] splits = line.split(",");
		
		if (splits.length != 6){
			throw new Exception("Unable to parse: " + line + ", there should be 6 field values");
		}
		
		for(String s : splits){
			if (s.isEmpty())
				throw new Exception("Unable to parse: " + line + ", an empty value present");
		}
		
		this.line = line;
		
		// parse
		functionCode = 		(splits[0].trim()).charAt(0);
		
		String xStr = 		splits[1].trim();
		if (xStr.equalsIgnoreCase("e"))
			x = Math.E;
		else if (xStr.equalsIgnoreCase("p"))
			x = getPiValue(functionCode);
		else
			x = Double.parseDouble(xStr);
		
		precision = 		Double.parseDouble(splits[2].trim());
		expectedOutput =	Double.parseDouble(splits[3].trim());
		undefinedOutput = 	(Integer.parseInt(splits[4].trim()) == 1) ? true : false;
		infiniteOutput = 	(Integer.parseInt(splits[5].trim()) == 1) ? true : false;
	}
	
	public String toString(){
		return  "---------- Data item: -----------" +
		"\n    functionCode: " + functionCode +
		"\n    x: " + x + 
		"\n    precision: " + precision + 
		"\n    expectedOutput: " + expectedOutput + 
		"\n    undefinedOutput: " + undefinedOutput + 
		"\n    infiniteOutput: " + infiniteOutput;
	}
	public char getFunctionCode() {
		return functionCode;
	}
	public void setFunctionCode(char functionCode) {
		this.functionCode = functionCode;
	}
	public double getX() {
		return x;
	}
	public void setX(double x) {
		this.x = x;
	}
	public double getPrecision() {
		return precision;
	}
	public void setPrecision(double precision) {
		this.precision = precision;
	}
	public double getExpectedOutput() {
		return expectedOutput;
	}
	public void setExpectedOutput(double expectedOutput) {
		this.expectedOutput = expectedOutput;
	}
	public boolean isUndefinedOutput() {
		return undefinedOutput;
	}
	public void setUndefinedOutput(boolean undefinedOutput) {
		this.undefinedOutput = undefinedOutput;
	}
	public boolean isInfiniteOutput() {
		return infiniteOutput;
	}
	public void setInfiniteOutput(boolean infiniteOutput) {
		this.infiniteOutput = infiniteOutput;
	}

	public String getLine() {
		return line;
	}
	
	
	/**
	 * Determines what will be the value of PI based on the selected function
	 * 
	 * @param func
	 * @return
	 */
	private double getPiValue(char func) {
		switch (func) {
		case 'a':
			return 180;
		case 'b':
			return 180;
		case 'c':
			return 180;
		case 'd':
			return Math.PI;
		case 'e':
			return Math.PI;
		case 'f':
			return Math.PI;
		}
		return 0;
	}
	
}